package com.cmc.cloud.cmclink.doc.service.si;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cmc.cloud.cmclink.doc.api.document.emums.DoOperationTypeEnum;
import com.cmc.cloud.cmclink.doc.api.document.rep.BlnoCntrStaticDto;
import com.cmc.cloud.cmclink.doc.api.document.rep.BlnoPageRespDto;
import com.cmc.cloud.cmclink.doc.api.document.rep.BlnoStatisticsRespDto;
import com.cmc.cloud.cmclink.doc.api.document.req.si.*;
import com.cmc.cloud.cmclink.doc.api.document.req.so.SoForecastBaseVO;
import com.cmc.cloud.cmclink.doc.api.document.req.so.SoForecastRespVO;
import com.cmc.cloud.cmclink.doc.entity.BlnoDO;
import com.cmc.cloud.cmclink.doc.entity.SoDO;
import com.cmc.cloud.cmclink.doc.vo.blnoblprintlogvo.BlnoPrintBatchOperationReqDto;
import com.cmc.cloud.cmclink.doc.vo.blnochargevo.BlnoCheckMsgReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnocntrvo.BlnoCntrUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnocntrvo.CntrBaseInfoVO;
import com.cmc.cloud.cmclink.doc.vo.blnofreightvo.BlnoFreightCalReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnolocalcostvo.BlnoLocaCoastExRespVO;
import com.cmc.cloud.cmclink.doc.vo.blnolocalcostvo.BlnoLocalCostExReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnoscnvo.BlnoScnUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.blnovo.*;
import com.cmc.cloud.cmclink.doc.vo.blnovo.operatevo.*;
import com.cmc.cloud.cmclink.doc.vo.blnovslvoyvo.BlnoVslvoyUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.operatelog.OperateLogRespVO;
import com.cmc.cloud.cmclink.doc.vo.voyagelock.VoyageLockImReqVO;
import com.cmes.framework.common.pojo.PageResult;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 提单主信息 Service 接口
 *
 * @author 集运管理员
 */
public interface BlnoService {

    /**
     * 创建提单主信息
     *
     * @param createReqVO 创建信息
     */
    void createBlno(@Valid BlnoCreateReqVO createReqVO);

    /**
     * 更新提单主信息
     *
     * @param updateReqVO 更新信息
     */
    void updateBlno(@Valid BlnoUpdateReqVO updateReqVO);

    /**
     * 删除提单主信息
     *
     * @param id 编号
     */
    void deleteBlno(Long id);

    /**
     * 获得提单主信息
     *
     * @param id 编号
     * @return 提单主信息
     */
    BlnoDO getBlno(Long id);

    /**
     * 获得提单主信息列表
     *
     * @param ids 编号
     * @return 提单主信息列表
     */
    List<BlnoDO> getBlnoList(Collection<Long> ids);

    /**
     * 获得提单主信息分页
     *
     * @param pageReqVO 分页查询
     * @return 提单主信息分页
     */
    PageResult<BlnoPageRespVO> getBlnoPage(BlnoPageReqVO pageReqVO);

    /**
     * si 修改，新增
     *
     * @param createReqVO si 数据
     * @param update 新增 false ，修改 true
     * @param userId 用户ID
     * @return id
     */
    Long createOrUpdateSi(BlnoInfoVO createReqVO, boolean update, String userId);

    /**
     * 提交 SI信息
     *
     * @param blnoInfoVO
     * @param userId
     */
    @Transactional(rollbackFor = Exception.class)
    Long commitSi(BlnoInfoVO blnoInfoVO, String userId);

    /**
     * 提交 SI信息
     *
     * @param blnoInfoVO
     *
     */
    Long commitSi(BlnoInfoVO blnoInfoVO);

    /**
     * 创建 SI主信息
     *
     * @param createReqVO 创建信息
     * @return 提单主信息
     */
    BlnoDO createOrUpdateSi(BlnoBaseInfoVO createReqVO);

    /**
     * 导出Si
     *
     * @param blnoBaseInfoExportVO 导出条件
     * @return 导出数据
     */
    List<BlnoPageRespVO> getExportList(BlnoBaseInfoExportVO blnoBaseInfoExportVO);

    /**
     * 获取提单详情
     *
     * @param blnoId 提单主表id
     * @return BlnoInfoVO
     */
    BlnoInfoVO getSiDetail(Long blnoId);

    /**
     * 通过提单号批量获取提单详情
     *
     * @param blNos 提单号列表
     * @return BlnoInfoVO 提单详情列表
     */
    List<BlnoInfoVO> getSiDetailListByBlNos(List<String> blNos);

    /**
     * 获得所有提单信息
     *
     * @param reqVO
     * @return List<BlnoRespVO>
     */
    List<BlnoTransferVO> getBlnoAll(BlnoTransferVO reqVO);

    /**
     * 获得提单主信息列表
     *
     * @param reqVO
     * @return List<BlnoDO>
     */
    List<BlnoDO> getBlnoWithFreightList(BlnoFreightCalReqVO reqVO);

    /**
     * 获得提单主信息列表
     *
     * @param reqVO
     * @param blLockFlag 锁船标记
     * @return List<BlnoDO>
     */
    List<BlnoDO> getBlnoWithFreightList(BlnoFreightCalReqVO reqVO, Boolean blLockFlag);

    /**
     * 获取提单详情
     *
     * @return List<BlnoDO>
     */
    List<BlnoDO> getBlnoWithLclList();

    /**
     * 对提单信息进行检查校验
     *
     * @param blnoCheckSiReqVO
     * @return BlnoCheckSiRespVO
     */
    BlnoCheckSiRespVO checkSi(BlnoCheckSiReqVO blnoCheckSiReqVO);

    /**
     * 对提单信息进行检查基础校验
     *
     * @param blnoInfoVO 校验信息
     * @param checkFlag 是否跳过SI状态校验(SI待审核)
     * @return Boolean
     */
    Boolean basicCheck(BlnoInfoVO blnoInfoVO, BlnoCheckSiRespVO blnoCheckSiRespVO,Boolean checkFlag);

    /**
     * 校验DCR
     *
     * @param blnoId 提单主表 id
     * @return 明细
     */
    SiDetailRespVO checkSiDcr(Long blnoId);

    /**
     * 获取提单操作日志
     *
     * @param blnoId 提单主表 id
     * @return 提单操作日志
     */
    List<OperateLogRespVO> getSiOperationLog(Long blnoId);

    /**
     * 对提单信息进行确认 并且生成draft件
     *
     * @param blnoCheckSiReqVO
     * @return BlnoCheckSiRespVO
     */
    BlnoCheckSiRespVO confirmSi(BlnoCheckSiReqVO blnoCheckSiReqVO);

    /**
     * 获得Local Charge费用信息
     *
     * @param reqVO
     * @return List<BlnoDO>
     */
    List<BlnoLocaCoastExRespVO> getBlnoWithLocalCostList(BlnoLocalCostExReqVO reqVO);

    /**
     * 设置 提单打印地
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void setIssuePlace(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 设置 提单打印日期
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void setIssueDate(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 设置 实际签单类型
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void operateSignType(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 设置 电子保函登记类型
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void setElgReceive(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 设置 正本保函登记类型
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void setLgReceive(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 设置 扣单标记
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void signRestriction(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 锁定提单
     * @param blnoOperateReqVO
     * @return
     */
    void setBlLock(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 取消 扣单 标记
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void cancelRestriction(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 清空 originalBl
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void cancelOriginalBl(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 清空 telex
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void cancelTelex(BlnoOperateReqVO blnoOperateReqVO);

//    /**
//     * 清空 telex
//     *
//     * @param blnoOperateReqVO
//     * @return List<BlnoDO>
//     */
//    @Transactional(rollbackFor = Exception.class)
//    void cancelTelex(BlnoOperateIdsReqVO blnoOperateReqVO);

    /**
     * 清空 electronicBl
     *
     * @param blnoOperateReqVO
     * @return List<BlnoDO>
     */
    void cancelElectronicBl(BlnoOperateReqVO blnoOperateReqVO);

    /**
     * 通过箱号
     *
     * @param containNo
     * @return CntrBaseInfoVO
     */
    CntrBaseInfoVO getContainInfo(String containNo);

    /**
     * 获得提单箱状态
     * @param blIdList
     * @return
     */
    List<String> getBlContainDepositStatus(@Valid BlnoOperateIdsReqVO blIdList);

    /**
     * 获得提单主信息
     * @param blnoDetailReqDto
     * @return
     */
    BlnoDO getBlno(BlnoDetailReqDto blnoDetailReqDto);
    /**
     * 获得提单统计信息
     * @param creator
     * @return
     */
    BlnoStatisticsRespDto getBlnoStatistics(String csmCode,String creator);
    /**
     * 获得提单分页信息
     * @param page
     * @param blnoPageReqDto
     * @return
     */
    IPage<BlnoPageRespDto> rpcPageBlnoInfo(IPage<BlnoPageRespDto> page, BlnoPageReqDto blnoPageReqDto);
    /**
     * 获得提单集装箱信息
     * @param blnoPageReqDto
     * @return
     */
    List<BlnoCntrStaticDto> rpcBlnoCntr(BlnoPageReqDto blnoPageReqDto);

    /**
     * 网厅-提单Draft 确认
     *
     * @param draftConfirmDto draft确认参数
     * @return
     */
    Boolean draftConfirm(DraftConfirmDto draftConfirmDto);

    /**
     * 网厅-提单Draft 确认 批量
     *
     * @param blnoPrintBatchOperationReqDto 提单打印批量操作参数
     * @return
     */
    Boolean batchDraftConfirm(BlnoPrintBatchOperationReqDto blnoPrintBatchOperationReqDto);

    /**
     * 网厅-批量刷新提单主体
     *
     * @param blnoPrintBatchOperationReqDto 提单打印批量操作参数
     * @return 成功刷新的提单主体列表
     */
    List<String> flushBlEntity(BlnoPrintBatchOperationReqDto blnoPrintBatchOperationReqDto);

    /**
     * 校验si 录入的箱信息 是否和so 的预配箱信息一致
     * @param bookingNos
     * @param blnoCntrs
     */
    void checkCntrSiInSo(List<String> bookingNos, List<BlnoCntrUpdateReqVO> blnoCntrs);

    /**
     * 更新si 录入的箱信息
     * @param updateDto
     */
    void updateSignType(BlnoSignTypeUpdateDto updateDto);

    /**
     * 获取提单IM分页
     *
     * @param pageVo pageVo
     * @return PageResult
     */
    PageResult<BlnoImPageRespVO> getBlnoImPage(@Valid BlnoImPageReqVO pageVo);

    /**
     * 导出提单IM
     *
     * @param reqVO reqVO
     * @return List<BlnoImPageRespVO>
     */
    List<BlnoImPageRespVO> exportBlnoIm(BlnoImPageReqVO reqVO);

    /**
     * 把提交的提单退回到草稿状态
     *
     * @param id id
     */
    void returnDraft(Long id);

    /**
     * blnoScns
     * @param blnoScns blnoScns
     */
    void checkCpfCode(List<BlnoScnUpdateReqVO> blnoScns);

    /**
     * 设置提单DO
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void setDO(@Valid BlnoOperateDoReqVO blnoOperateReqVO);

    /**
     * 取消提单DO
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void cancelDO(@Valid BlnoOperateCancelDoReqVO blnoOperateReqVO);

    /**
     * notedTelex
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void notedTelex(@Valid BlnoOperateIdsReqVO blnoOperateReqVO);

    /**
     * lockDO
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void lockDO(@Valid BlnoOperateLockDoReqVO blnoOperateReqVO);

    /**
     * unLockDO
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void unLockDO(@Valid BlnoOperateIdsReqVO blnoOperateReqVO);

    /**
     * unLockDO
     * @param reqVos reqVos
     */
    void unLockDO(List<VoyageLockImReqVO> reqVos);

    /**
     * lockCharge
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void lockCharge(@Valid BlnoOperateLockChargeReqVO blnoOperateReqVO);

    /**
     * unLockCharge
     * sendEDO
     *
     * @param blnoIds
     * @return List<String>
     */
    BlnoCheckMsgReqVO lockChargeCheck(@NotNull(message = "提单主信息id 列表") List<Long> blnoIds);

    /**
     * setTransitTerm
     *
     * @param blnoIds
     * @param commodityCn
     */
    void setCommodityCn(List<Long> blnoIds, String commodityCn);

    /**
     * setTransitTerm
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void setTransitTerm(@Valid BlnoOperateTransitTermReqVO blnoOperateReqVO);

    /**
     * setStuffLocation
     * @param blnoOperateReqVO blnoOperateReqVO
     */
    void setStuffLocation(@Valid BlnoOperateStuffLocationReqVO blnoOperateReqVO);

    /**
     * setDOPart
     * @param blnoOperateReqVos blnoOperateReqVO
     */
    void setDoPart(@Valid List<BlnoOperateDoPartReqVO> blnoOperateReqVos);

    /**
     * printDocument
     *
     * @param response         response
     * @param blnoOperateReqVO blnoOperateReqVO
     * @return
     */
    String printDocument(HttpServletResponse response, @Valid BlnoOperatePrintDocumentReqVO blnoOperateReqVO);

//    /**
//     * setSendArriveNotice
//     * @param blnoOperateReqVO blnoOperateReqVO
//     */
//    void setSendArriveNotice(@Valid BlnoOperateDoReqVO blnoOperateReqVO);

    /**
     * getDOPart
     * @param blnoIds blnoIds
     * @return List<BlnoDoPartRespVO>
     */
    List<BlnoDoPartRespVO> getDoPart(@NotNull(message = "提单主信息id 列表") List<Long> blnoIds);

    /**
     * 获得Terminal
     *
     * @param blnoVslvoyList
     */
    void setVslvoyTerminal(List<BlnoVslvoyUpdateReqVO> blnoVslvoyList,String imExType);

    /**
     * 锁定提单DO
     * @param reqVos reqVos
     */
    void lockDO(@Valid List<VoyageLockImReqVO> reqVos);

    /**
     * 通过提单号查询提单数据
     *
     * @param blNos 提单号列表
     * @return 提单数据列表
     */
    List<BlnoDO> getBlNoDoListByBlNo(List<String> blNos);

    /**
     * 创建si 更改记录
     * @param createReqVO
     * @return void
     */
    void createSiChange(BlnoInfoVO createReqVO);

    /**
     * 判断是否可以 创建si 更改记录
     * @param id 提单主表id
     * @return Boolean
     */
    Boolean checkSiChange(Long id);

    /**
     * 发送提单
     *
     * @param blnoOperateIdsReqVO 发送提单参数
     * @param doOperationTypeEnum 发送提单参数
     */
    void sendEdo(BlnoOperateIdsReqVO blnoOperateIdsReqVO, DoOperationTypeEnum doOperationTypeEnum);

    /**
     * 通过主键ID批量查询blNo(删除未删除都查)
     * @param ids 主键ID集合
     * @return    blNo集合
     */
    List<String> getBlNoByIdListNotDependOnDeleted(List<Long> ids);

    /**
     * 批量查询blNo
     *
     * @param blNoList 主键ID集合
     * @return blNo集合
     */
    Map<String, List<BlnoDO>> findBlnoByBlNos(List<String> blNoList);

    /**
     * 返回true 弹出提示给用户确认
     * @param assertNoticeVO
     * @return Boolean
     */
    Boolean assertGiveNotice(AssertNoticeVO assertNoticeVO);

    /**
     * 多so 合si 校验
     * @param blnoMultipleSoVO
     * @return List<SoDO>
     */
    List<SoDO> checkSoCombineSi(BlnoMultipleSoVO blnoMultipleSoVO);

    /**
     * 多so 合si 创建
     * @param blnoMultipleSoCreateVO
     */
    Long createSoCombineSi(BlnoMultipleSoCreateVO blnoMultipleSoCreateVO);

    /**
     * 多so 合si 创建
     * @param blnoMultipleSoCreateVO
     */
    Long commitSoCombineSi(BlnoMultipleSoCreateVO blnoMultipleSoCreateVO);

    /**
     * @param blnoForecastReqVO
     * @return  List<SoForecastRespVO>
     */
    List<SoForecastRespVO> getForecastInfo(BlnoForecastReqVO blnoForecastReqVO);

    /**
     * 设置提单船期的信息
     * @param blnoVslvoys
     * @return  List<SoForecastRespVO>
     */
    void setShippingScheduleTime(List<BlnoVslvoyUpdateReqDto> blnoVslvoys);

    /**
     * 青岛码头数据对比 自有数据
     * @param blnoCntrCntaoReqVO
     * @return  List<BlnoCntrCntaoVO>
     */
    List<BlnoCntrCntaoVO> selectCntaoCntr(BlnoCntrCntaoReqVO blnoCntrCntaoReqVO);

    /**
     * 青岛码头数据 校验
     * @param blnoCntrCntaoReqVO
     * @return  List<BlnoCntrCntaoVO>
     */
    BlnoCntrCntaoCompareRespVO checkCntaoCntr(BlnoCntrCntaoReqVO blnoCntrCntaoReqVO) throws IOException;

    /**
     * 提单货描 疑似危险品 货物AI 检测
     * @param map
     */
    void saveSuspectedDg(Map<String,String> map);

    /**
     * 多SO合并提单查询SO预配箱信息
     * @param siId
     * @param blNo
     * @return
     */
    List<SoForecastBaseVO> getSoForecastBySoId(Long siId,String blNo);
}
